package org.oslims.client.uicomponents;

import org.oslims.domain.BooleanParameterResult;
import org.oslims.domain.DateParameterResult;
import org.oslims.domain.NumberParameterResult;
import org.oslims.domain.ParameterResult;
import org.oslims.domain.TextParameterResult;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.InputElement;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.SelectElement;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Window;

public class ParameterResultCell extends AbstractCell<ParameterResult> {

	private Boolean editPossible;

	public ParameterResultCell(Boolean editPossible) {
		this.editPossible = editPossible;
	}

	@Override
	public boolean consumesEvents() {
		return true;
	}

	@Override
	public Object onBrowserEvent(Element parent, ParameterResult value, Object viewData, NativeEvent event, ValueUpdater<ParameterResult> valueUpdater) {

		if (value instanceof TextParameterResult) {
			TextParameterResult result = (TextParameterResult) value;

			if (valueUpdater != null && "change".equals(event.getType())) {
				InputElement input = parent.getFirstChild().cast();
				result.setResult(input.getValue());
				valueUpdater.update(result);
			}
		} else if (value instanceof NumberParameterResult) {
			NumberParameterResult result = (NumberParameterResult) value;

			if (valueUpdater != null && "change".equals(event.getType())) {
				InputElement input = parent.getFirstChild().cast();

				try {
					result.setResult(Double.parseDouble(input.getValue()));
				} catch (IllegalArgumentException e) {
					if (!input.getValue().isEmpty())
						Window.alert("Please enter a valid Number!");
				}
				valueUpdater.update(result);
			}
		} else if (value instanceof DateParameterResult) {
			DateParameterResult result = (DateParameterResult) value;

			if (valueUpdater != null && "change".equals(event.getType())) {
				InputElement input = parent.getFirstChild().cast();

				try {
					result.setResult(DateTimeFormat.getShortDateTimeFormat().parse(input.getValue()));
				} catch (IllegalArgumentException e) {
					if (!input.getValue().isEmpty())
						Window.alert("Please enter a valid Date!");
				}
				valueUpdater.update(result);
			}
		} else if (value instanceof BooleanParameterResult) {
			BooleanParameterResult result = (BooleanParameterResult) value;

			if (valueUpdater != null && "change".equals(event.getType())) {
				SelectElement select = parent.getFirstChild().cast();

				if (select.getSelectedIndex() == 1) {
					result.setResult(true);
				} else if (select.getSelectedIndex() == 2) {
					result.setResult(false);
				}

				valueUpdater.update(result);
			}
		} else {
			throw new IllegalArgumentException("This Parameter Type is not implemented!");
		}

		return viewData;
	}

	@Override
	public void render(ParameterResult value, Object viewData, StringBuilder sb) {

		if (!value.getState().equals("In Analyzing") || !editPossible) {
			sb.append(value.toString());
			return;
		}

		if (value instanceof TextParameterResult) {
			TextParameterResult result = (TextParameterResult) value;

			sb.append("<input type='text'");
			if (result.getResult() != null) {
				sb.append(" value='" + result.getResult() + "'");
			}
			sb.append("></input>");

		} else if (value instanceof NumberParameterResult) {
			NumberParameterResult result = (NumberParameterResult) value;

			sb.append("<input type='text'");
			if (result.getResult() != null) {
				sb.append(" value='" + result.getResult() + "'");
			}
			sb.append("></input>");

		} else if (value instanceof DateParameterResult) {
			DateParameterResult result = (DateParameterResult) value;

			sb.append("<input type='text'");
			if (result.getResult() != null) {
				sb.append(" value='" + DateTimeFormat.getShortDateTimeFormat().format(result.getResult()) + "'");
			}
			sb.append("></input>");

		} else if (value instanceof BooleanParameterResult) {
			BooleanParameterResult result = (BooleanParameterResult) value;

			sb.append("<select>");

			if (result.getResult() == null) {
				sb.append("<option selected='selected'>");
			} else {
				sb.append("<option>");
			}
			sb.append("</option>");

			if (result.getResult() != null && result.getResult()) {
				sb.append("<option selected='selected'>");
			} else {
				sb.append("<option>");
			}
			sb.append("True");
			sb.append("</option>");

			if (result.getResult() != null && !result.getResult()) {
				sb.append("<option selected='selected'>");
			} else {
				sb.append("<option>");
			}
			sb.append("False");
			sb.append("</option>");

			sb.append("</select>");

		} else {
			throw new IllegalArgumentException("This Parameter Type is not implemented!");
		}
	}
}
